package thread.wang_bao_ling.c21;

import java.util.concurrent.atomic.AtomicStampedReference;

/**
 * 演示AtomicStampedReference处理ABA问题
 */
public class AtomicStampedReferenceTest {

    static AtomicStampedReference<User> userASR= new AtomicStampedReference<User>(null,0);

    public static void main(String[] args) throws InterruptedException {
        User user1=new User();


        //线程1启动，想将user初始值null设置成user1
        new Thread(()->{
            User user=userASR.getReference();
            int stamp=userASR.getStamp();
            //此时输出的期望值user为null，stamp为0
            System.out.println("t1线程期的user值为："+user+"；期望的票据为"+stamp);
            try {
                //通过线程休眠的方式模拟线程在获取期望值后被挂起
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //将user设置成user1,虽然user的期望值依然为null,但票据已经变了，最终修改失败
            boolean result=userASR.compareAndSet(user, user1,  stamp,userASR.getStamp()+1);
            System.out.println("t1线程修改结果："+result);
        },"t1").start()
        ;
        Thread.sleep(1000);
        //在t1线程休眠1s后，t2线程启动了，它将userASR的引用从初始值null设置成user1后又设置回null，即ABA
        new Thread(()->{
            userASR.compareAndSet(userASR.getReference(), user1, userASR.getStamp() , userASR.getStamp() + 1);
            userASR.compareAndSet(userASR.getReference(),null, userASR.getStamp() , userASR.getStamp() + 1);
            System.out.println("t2线程修改后当前的user值为："+userASR.getReference()+"；t2线程修改后当前的票据为"+userASR.getStamp());
        },"t2").start();

    }
}
